After entering the Prompt string as the first parameter, you specify
the maximum number of characters the user can use to respond as the second.
The maximum can be any number between 1 and 127. Although STRINGS works
with strings up to 127 characters long, remember that DOS programs can only
accept a command line with a total length of 127 characters. Thus,
setting an environment variable to a long length may cause DOS to overflow
the command line of a program that uses that variable.
The third and final ASK parameter is a flag that tells STRINGS not
to echo what the user types to the screen. This allows a .BAT file to
prompt for a password without its becoming visible on the screen.
When the third parameter is a 1, STRINGS echoes asterisks to the screenin place of the characters being typed. If the parameter is 2, STRINGS
does not echo any characters to the screen. If neither flag is specified,
the user response is echoed.
Three of the math functions--ADD, SUB, and MUL--have been revised toallow you to add or multiply up to 10 different numbers in one STRINGS
command. For the SUB command, up to nine numbers can be subtracted from
the first number in the series. Thus, the command
STRINGS SUB 10, 2, 1
returns the value 7, which is computed as 10 - 2 - 1.
STRING HANDLING COMMANDS
This first set of the new STRINGS commands goes to the root of the
program's functionality; its ability to manipulate strings.
The PARSE command separates a string into different sections and
returns one of those sections. This command makes it easy to separate
the different directory strings from the PATH environment variable, for
example. The full syntax for PARSE is
STRINGS [dest var =] PARSE String, section number, Separator char
The three PARSE parameters are the string, the section number to return,
and the separator character to be used to differentiate among sections.
The small batch file, CHECKEX.BAT, (listed below in Figure 2) uses the
PARSE command to search the PATH to determine the execution order of the
program name you provide. This is exactly what COMMAND.COM does when it
is asked to launch a program. On my machine, the command
CHECKEX brief
returned the list
C:\UTIL\B.BAT
C:\EDITORS\BRIEF\B.EXE
This return discloses a problem: If DOS searches the full path, B.BAT
will execute, but B.EXE never will. It seems I should rename that batch
file!
As shown by the STRINGS line in CHECKEX.BAT, the PARSE command here
uses the PATH environment variable as the starting string. It uses theINDEX environment variable to run through the different directories in
sequence. And it uses the semicolon to tell where one directory ends
and the next one begins on the PATH statement.
ADDCOMMAS is a simple command that inserts commas every three digits in
a number you supply as its argument. If you enter
STRINGS ADDCOMMAS 12345678
STRINGS will return
12,345,678
The REPEAT command simply creates a string that consists of the
same character repeated n times. For example, the command
STRINGS REPEAT 25, A
will return a string with 25 As. The maximum value for n is 127.
The FILEDATE command returns the date on a file. It takes filename
as its only argument, and the date is returned in a mm-dd-yyyy format.
The FILETIME command similarly returns the time when a file was last
written, in a hh:mm:ss am/pm format.
TRUEVER returns the true DOS version number, regardless of what is
reported by the normal VER command. With the introduction of the SETVER
device driver in DOS 5.0, you can trick programs into believing that theyare running under a different version of DOS than they actually are.
There are times, however, when you need to know the real DOS version:
hence TRUEVER. The number returned is the major version number times100, plus the minor version number. For example, in DOS 5.0 the number
returned is 500.
Although the SETVER device driver is only available on DOS 5.0
(and later), the TRUEVER command will still work under DOS versions 2.0
though 4.0; it simply returns the same value as does the STRINGS VER
command.
The FILES command returns the maximum number of files that can be
open on the system at one time. This number is usually, but not always,
the number shown in the FILES= statement in your CONFIG.SYS file.
Programs such as Windows or Jeff Prosise's UMBFILES can change the
maximum number of files, however, so FILES is a handy way to confirm
that a program will have enough file handles to run.
The LASTDRIVE command returns the last drive letter that can be
assigned to a disk. This is usually set with the LASTDRIVE= line in
the CONFIG.SYS file, but again, some programs can modify that value.
LASTDRIVE is useful when a batch file must perform an action on all
possible drives in the system.
The CODEPAGE command allows batch files to determine the currently
active codepage. The codepage number determines the character set your
system uses. Most US systems use codepage 437, which is the standard
character set. Codepage 850, on the other hand, replaces some of the
graphic characters in the 437 codepage with characters used in European
languages. To query the active codepage, simply enter STRINGS CODEPAGE.
The COUNTRY command returns the country information for the system.Since DOS 2.0, parameters such as the currency symbol, thousands separator,
and the date format can be configured for different countries. The table
in Figure 3 (see below) shows what the COUNTRY command returns for
different values of the first parameter, assuming you live in the U.S.
Entering STRINGS BIOSDATE returns a string, normally containing thedate, from address F000:FFF5h in the BIOS ROM. The command assumes thedate will be in the first 8 bytes following the address, as it is in most
PC compatibles. The command takes no arguments.
The GETKEY command waits for the user to press a key then returns
the ASCII value and its scan code. While the ASK command is limited to
returning ASCII characters, GETKEY is also able to return non-ASCII keys
such as the cursor keys and function keys. The codes are returned with
the ASCII code first, followed by a space, followed by the scan code.
It is at this point that you can use the PARSE command to operate separately
on the ASCII and scan codes returned by the keystroke.
The next four commands--AND, OR, XOR, and NOT--extend the math commands
to logical operations. The AND command returns the logical AND of the
parameters you supply. Likewise, the OR and XOR commands return thelogical OR and exclusive OR of their respective parameters. Like the ADD,
SUB, and MUL commands, the AND and OR commands can take up to ten
parameters. XOR, of course, takes only two. The NOT command returns the
one's complement of its single parameter.
The CONVERT command, which converts a number to a different base,
became necessary once the /B switch was introduced. This command takes
two parameters: the number to be converted and the new number base.
As with all commands, both the number and new base parameters are
interpreted in the base specified in the /B switch. For example, to
convert the hexadecimal (base 16) number 2FB to decimal, the command
would be
STRINGS /B16 CONVERT 2FB, A
Note here that the second parameter, A, is not the character A, but rather
the number 10, in hexadecimal. Going the other way, the command
STRINGS CONVERT 763, 16
returns the hexadecimal number 2FB. (Because the default base for STRINGSis base 10, the /B switch is not required in this case.)
TIME & DATE COMMANDS
The next four commands return times and dates. The DAY function
returns the current day of the week:STRINGS DAY will return Tuesday if
today is Tuesday. As an added feature, if the DAY command is passeda number between 1 and 7, it returns the day corresponding to that number.STRINGS DAY 6 returns the string Friday, for example.
The MONTH command is entirely similar to the DAY command, and again,if passed a number between 1 and 12, it returns the month corresponding
to that number.
The DATE command returns the current date in a mm-dd-yyyy format.
The Time command similarly returns the current time in a hh:mm:ss am/pm
format. Users requiring a different format for the time and date can
easily use the multitude of STRINGS commands to present the data in any
form they wish.
SYSTEM MEMORY
The enhanced STRINGS contains a number of commands that deal with
system memory. MEMTOTAL returns the total conventional (DOS) memory
available to the system, and MEMFREE returns the amount of conventional
memory still available for use. Note, however, that the MEMFREE command
will respond differently when STRINGS is installed as resident.
COMMAND.COM does not release its memory when resident commands are
executed, so if STRINGS is resident when this call is made, the amount
of free conventional memory indicated will be small or nonexistent.
The XMSTOTAL command returns the total amount of extended memory inthe system, and XMSFREE returns the amount of free extended memory.
Normally, extended memory is managed by an extended memory (XMS) manager,
such as HIMEM.SYS. If no XMS manager is present, STRINGS uses a BIOSInt 15h call to determine the amount of extended memory. In this case,
as there is no memory manager present to differentiate between free and
used extended memory, both the XMSFREE and XMSTOTAL calls will return
the same number. XMSVER returns the version of the XMS memory manager
in use; if none is present, the command returns 0.
Expanded memory is correspondingly queried with the EMSTOTAL, EMSFREE,
and EMSVER commands. Again, if no expanded memory manager is installed,
EMSVER will return 0.
The final memory command is UMBLARGE. This command returns the size
of the largest free upper memory block (UMB). UMBs are blocks of memory
that reside between the video memory at A000h and the BIOS ROM at E000h
or F000h. This command is useful for determining whether there is room
in upper memory for TSRs.
PROGRAMMER'S COMMANDS
The next series of commands are designed for the PC programmer.
They allow batch files to actually perform functions previously reserved
for .COM and .EXE files.
PEEK, the first of these commands, allows a batch file to read a
series of bytes from memory. The syntax of the PEEK command is
The /B16 switch is used to tell STRINGS to ``talk'' in hexadecimal,
which is handy because most PC programming is done in base 16. The 21
indicates that you want STRINGS to call Interrupt 21h, the DOS command
dispatcher. The 3400 indicates that AX is to be loaded with 3400h when
the interrupt is called. In fact, you only need to load AH (with 34h),
but the command has no way of loading the individual byte halves of the
registers. Thus, you end up loading AX with 3400, which puts 34 in AH
and 00 in AL. The remaining registers for this interrupt are not
important, and actually they don't have to be included at all. STRINGS
loads 0 in the registers not specified.
On my machine running MS-DOS 5.0, the command above returns thestring
3400 321 0 0 0 0 0 0 116 7246
The INTERRUPT command always returns a string with ten numbers, each
separated by a space. Because the /B16 switch was used, all the values
are in hexadecimal. The first number, 3400, is the value of the AX
register when the interrupt returns. The important values, however,
are 321, the value of BX on the return; and 116, which is the returned
value of ES. The MS-DOS Programmer's Reference indicates that the address
of the InDOS flag will be returned in ES:BX.
You can now use the PEEK command to check the state of the InDOS
flag. That command would look like this:
STRINGS /B16 PEEK 116 321
Although knowing the address of the InDOS flag has little use for
batch file programming, other interrupts can come in quite handy. The
undocumented interrupt 21 AX=5200 returns a pointer to DOS's list of
lists. This pointer is quite useful for checking out the current stateof the machine. Shortly I'll present a batch file that uses the list of
lists to determine the current memory usage for the system.
The final programmer's command is SCAN. This command searches memoryfor a series of bytes. The segment to search and the starting offset
are specified in the first two parameters. The remaining parameters
(up to an additional eight) are the bytes to use in the search.
For example, to search the segment 23h for the byte series 10 20 30 40
the command would be
STRINGS /B16 SCAN 23, 0, 10, 20, 30, 40
Since SCAN searches only the segment specified, additional SCAN commandsare needed for any searches beyond the original segment.
When used in conjunction with the improved VAL command, SCAN cansearch for an ASCII string in memory. An example is shown in the followingbatch code fragment, which searches the DOS kernel for the string ``NUL":
STRINGS /B16 VALSTR = VAL NUL
STRINGS /B16 /P SCAN 116 0 %VALSTR%
As previously discussed, the VAL command returns the ASCII numbers
for each of the characters in the first parameter. In this case, because
the /B16 switch is used, VAL returns the numbers 4E 55 4C as a series of
hex bytes. These bytes are assigned to the VALSTR environment variable.
The new InDOS command mentioned above starts at offset 0 and uses the
VALSTR environment variable for its remaining arguments. On my machine,
this fragment returns the address 116 52, which is the address for theNUL device driver name. That address is important because the NUL devicedriver is the first in the DOS device driver chain.
Two additional notes about this batch fragment are in order. First,
the lack of commas separating the parameters in the SCAN command is not
a typo. The /P switch is used here to change the parse character to a
space. This is convenient, since the VAL command returns its numbers
separated by spaces.
The second important detail concerns the consistent use of the /B
switch. While it may not seem that the /B switch would be needed for
either command, if it is used in the VAL command it must be used in the
SCAN command. Since VAL uses a /B16 switch, it returns its numbersin hex. Because the result from the VAL command is used in the SCAN
command, SCAN must use the same base. Why was the /B16 switch used in
the first place? Remember that the DOS segment returned by the INTERRUPT
command was returned in hexadecimal, which forced the use of the /B
switch since we used that number. Just follow this simple rule: If
parameters are shared across STRINGS commands, they should use the same
base, or you should use the CONVERT command to change the parameters
to the proper base.
STRINGS MANAGEMENT
The final group of new STRINGS commands are to manage STRINGS itself.
STRINGSVER returns the version of STRINGS currently being used. Since
this command did not exist in the first version of STRINGS, calling it
with STRINGS1 will result in an error message and a return code of 1.
If STRINGSVER returns a nonzero ERRORLEVEL code, then STRINGS 1.x is
running. For the present version of STRINGS, the STRINGSVER command
returns the ASCII string 200 and a return code of 0.
The INSTALLED command returns a 1 if STRINGS is currently installed
as a TSR extension to COMMAND.COM. If STRINGS is not installed, a 0 is
returned. This command is useful for those situations in which a
STRINGS command might produce different results if the utility were
installed. MEMFREE represents one such case, and the use of returncodes may be another.
INSIDE STRINGS
For the most part, the enhanced version of strings simply involved
adding procedures for the new functions. The main change to the program
itself was the rewriting of the command parsing routine to use less memory.This was necessary so that STRINGS could be turned into a TSR. Of greatestprogramming interest, however, is the hook into COMMAND.COM's internalcommand dispatcher.
In Undocumented DOS, coauthor Jim Kyle has an informative chapter oncommand interpreters. It describes an undocumented ``back door'' into
COMAND.COM that allows TSRs to hook into the internal command dispatcher.This back door was first included in DOS 3.3 so that DOS's APPEND commandcould check on any subsequent APPEND commands. Fortunately for programmers,
that door has remained open in all later DOS releases.
When you enter a command at the DOS command line, COMMAND.COM must
determine whether the command is an internal function to be executed or
an external program that must be launched. Before making its decision,
COMMAND.COM calls the Multiplex Interrupt (Int 2Fh) with AX equal to
AE00h. At the time of the call, DX is loaded with FFFFh, BX is pointing
to a buffer that contains an exact replica of the command line just typed,
and SI points to a buffer that contains the potential command in
uppercase preceeded by a length byte.
TSRs such as STRINGS that hook into this call must compare the
command to which SI points with the command they wish to handle. For
STRINGS, that means checking to see whether SI is pointing to the ASCII
string "STRINGS".
A TSR that wants to claim the command puts 0FFh in AL, copies the
comand line pointed to by BX into an internal buffer, and returns to
COMMAND.COM. Otherwise the TSR must pass the Multiplex request down
the interrupt chain with all registers unmodified.
If a TSR claims the command, COMMAND.COM calls the Multiplex
Interrupt again, this time with AX loaded with AE01h. Having claimed it,
the TSR must now execute the command. While most of the registers during
this call are the same as in the AE00h call, Kyle recommends that a TSR
should copy the buffer from the earlier AE00h call because not all the
registers are explicitly loaded before the AE01h call. Once the commandhas been completed, the TSR should zero the size byte in the buffer to
which SI points. This tells COMMAND.COM that the command has been
processed.
While STRINGS doesn't provide every possible function a batch file
might want, the inclusion of such commands as PEEK, POKE, and INTERRUPT
allow the programmer to create just about any command. An an example of
this power is shown in BATMEM.BAT, which is listed below in Figure 5.
BATMEM scans the DOS memory blocks and displays the blocks that arebeing used as well as the ones that are free. BATMEM is similar to the
MEM command that has been included in DOS since version 4.0. Among the
STRINGS functions BATMEM uses are INTERRUPT, PARSE, CHAR, PEEK, andADDCOMMAS.
Notice that in BATMEM, STRINGS is installed with /I at the beginning
of the batch file and removed with /U at the end. These two switches double
the execution speed. If you don't want STRINGS installed and removed,
simply delete the /I and /U switches; the remainder of the batch file
will be unaffected.
Programs like BATMEM give but a taste of the world STRINGS opens to
enterprising batch file writers. To supplement STRINGS own commands, you
may wish to acquire Michael J. Mefford's excellent BATCHMAN utility in
the January 30, 1990 issue of PC Magazine. Like STRINGS, BATCHMAN is
available on PC MagNet.
The ability to perform low-level actions, coupled with the convenient
features of STRINGS's high-level commands, provide a wealth of new
opportunities for the once-lowly batch file. Try STRINGS, and your batch
files will never be the same.
----------------------------------------------------------------------------DOUGLAS BOLING IS A CONTRIBUTING EDITOR TO PC MAGAZINE.